package com.hxd.otc.net;

import android.app.Activity;
import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.hxd.otc.R;
import com.hxd.otc.base.BaseApplication;
import com.hxd.otc.base.BaseBean;
import com.hxd.otc.dialog.ConfirmValidTypeVerCodeDialog;
import com.hxd.otc.event.Event;
import com.hxd.otc.utils.ResourceUtil;
import com.hxd.otc.utils.UIUtils;

import org.greenrobot.eventbus.EventBus;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;


/**
 * description:  订阅者封装（用于非文件下载请求）
 * 作用：
 * 在onError中进行统一的异常处理，得到更直接详细的异常信息
 * 在onNext中进行统一操作，如请求回来后，先判断token是否失效，如果失效则直接跳转登录页面
 * 在onNext中对返回的结果进行处理，得到更直接的数据信息
 * 可在onSubscribe中进行请求前的操作，注意，onSubscribe是执行在 subscribe() 被调用时的线程，
 * 所以如果在onSubscribe里进行UI操作，就要保证subscribe()也是调用在UI线程里。
 */

public abstract class BaseObserver<T> implements Observer<BaseBean<T>> {

    public static final int SUCCESS = 10000000;
    public static final int ERROR = 1; //未知错误
    public static final int TOKEN_MISS = -8;
    public static final int TOKEN_NOT_MATCH = -5;
    public static final int PAY_VALID_INVALID = -9;//支付验证失效，需要重新校验支付验证
    public static final int SERVER_UPDATING_CODE = -6;//系统开关，如系统服务升级中
    private boolean postTokenMissEvent = true;

    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onComplete() {

    }

    @Override
    public void onError(Throwable e) {
        if (e instanceof Exception) {
            //访问获得对应的Exception
            ExceptionHandler.ResponseThrowable responseThrowable = ExceptionHandler.handleException(e);
            onError(responseThrowable.code, responseThrowable.message);
        } else {
            //将Throwable 和 未知错误的status code返回
            ExceptionHandler.ResponseThrowable responseThrowable = new ExceptionHandler.ResponseThrowable(e, ExceptionHandler.ERROR.UNKNOWN);
            onError(responseThrowable.code, responseThrowable.message);
        }
    }

    @Override
    public void onNext(BaseBean<T> response) {
        if (response.getCode() == SUCCESS) {
            String msg = response.getMsg();
            if ("success".equals(msg)) {
                msg = "";
            }
            onNext(msg, response.getData());
        } else if (response.getCode() == TOKEN_MISS || response.getCode() == TOKEN_NOT_MATCH) {
            if (postTokenMissEvent) {
                EventBus.getDefault().post(new Event.TokenMissEvent(0));
            }
            onError(TOKEN_MISS, "");
        } else if (response.getCode() == PAY_VALID_INVALID) {//支付验证失效，需要重新校验支付验证
            Activity topActivity = BaseApplication.getInstance().getTopActivity();
            if (topActivity == null) {
                onError(response.getCode(), response.getMsg());
            } else {
                ConfirmValidTypeVerCodeDialog confirmValidTypeVerCodeDialog = new ConfirmValidTypeVerCodeDialog(topActivity);
                confirmValidTypeVerCodeDialog.setCanceledOnTouchOutside(false);
                confirmValidTypeVerCodeDialog.show();
                onError(response.getCode(), "");
            }

        } else if (response.getCode() == SERVER_UPDATING_CODE) {
            String errMsg = response.getMsg();
            errMsg = TextUtils.isEmpty(errMsg) ? ResourceUtil.getString(R.string.system_service_upgrade_in_progress) : errMsg;
            Activity topActivity = BaseApplication.getInstance().getTopActivity();
            if (topActivity == null) {
                onError(response.getCode(), errMsg);
            } else {
                UIUtils.showServerUpdatingDialog(topActivity, errMsg);
                onError(response.getCode(), "");
            }
        } else {
            onError(response.getCode(), response.getMsg());
        }

    }

    //具体实现下面两个方法，便可从中得到更直接详细的信息
    public abstract void onNext(@NonNull String msg, @NonNull T t);

    public abstract void onError(int errType, @NonNull String errMessage);

    public interface TokenMissListener {
        void tokenMiss();
    }

    private TokenMissListener mTokenMissListener;

    public void setPostTokenMissEvent(boolean postTokenMissEvent) {
        this.postTokenMissEvent = postTokenMissEvent;
    }
}
